package com.ecarx.camera.ui.camera.dvr;

import static com.ecarx.camera.constant.Constants.ANIMATION_FAST_MILLIS;
import static com.ecarx.camera.constant.Constants.ANIMATION_SLOW_MILLIS;

import android.annotation.SuppressLint;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.text.TextUtils;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.TextView;
import android.widget.ToggleButton;

import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;

import com.ecarx.camera.R;
import com.ecarx.camera.ui.camera.ICameraUI;
import com.ecarx.camera.ui.contract.IMainView;
import com.ecarx.camera.utils.LogUtils;
import com.ecarx.camera.utils.Utils;
import com.ecarx.camera.worker.camera.ICameraWorker;
import com.ecarx.camera.worker.camera.dvr.DvrCameraWorker;
import com.ecarx.camera.worker.sound.SoundPlayManger;

public class DvrCameraUI implements ICameraUI {
    private static final String TAG = "DvrCameraUI";

    private ICameraWorker mCameraWorker;

    private IMainView mMainView;
    private Fragment mFragment;

    private View mView;

    private View mVideoRecordingIndicatorLay;
    private TextView[] mDayNightFgColorTvs;
    private TextView mVideoRecordingTimeTxt;
    private Button mTakePhotoBtn;
    private ToggleButton mRecordVideoBtn;
    private ToggleButton mMuteVideoBtn;
    private View mErrorView;
    private TextView mErrorDescTxt;

    /**
     * 录制按钮的touch事件监听
     */
    @SuppressLint("ClickableViewAccessibility")
    private final View.OnTouchListener mRecordBtnTouchListener = (v, event) -> {
        LogUtils.d(TAG, "record_video_btn-> onTouch, event:" + (event == null ? null : event.getAction()));
        if (event != null && MotionEvent.ACTION_UP == event.getAction()) {
            if (!checkDvrSdcardExists() || mCameraWorker == null) {
                return true;
            } else {
                boolean isNowChecked = (mRecordVideoBtn != null && mRecordVideoBtn.isChecked());
                LogUtils.d(TAG, "record_video_btn-> click, now checked:" + isNowChecked);
                if (isNowChecked) {
                    mCameraWorker.stopRecordVideo();
                } else {
                    mCameraWorker.startRecordVideo();
                }
            }
        }
        return false;
    };

    /**
     * 录制按钮状态切换监听
     */
    private final CompoundButton.OnCheckedChangeListener mRecordOnCheckedChangeListener = new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            LogUtils.d(TAG, "record_video_btn-> onCheckedChanged, isChecked:" + isChecked);
            if (mRecordVideoBtn != null) {
                mRecordVideoBtn.setEnabled(false);
            }
        }
    };

    @Override
    public void init(IMainView mainView, Fragment fragment) {
        mMainView = mainView;
        mFragment = fragment;
    }

    @Override
    public void bindViews(View view) {
        this.mView = view;
        mVideoRecordingIndicatorLay = view.findViewById(R.id.layout_dvr_video_recording);
        mVideoRecordingTimeTxt = view.findViewById(R.id.tv_video_recording_time);
        mTakePhotoBtn = view.findViewById(R.id.btn_take_photo);
        mRecordVideoBtn = view.findViewById(R.id.tbtn_record_video);
        mMuteVideoBtn = view.findViewById(R.id.tbtn_mute_video);
        mErrorView = view.findViewById(R.id.camera_error_view);
        mErrorDescTxt = view.findViewById(R.id.camera_error_desc);

        mDayNightFgColorTvs = new TextView[] {
                view.findViewById(R.id.tv_video_recording_tip),
                mVideoRecordingTimeTxt,
                mTakePhotoBtn,
                mRecordVideoBtn,
                mMuteVideoBtn,
        };

        mTakePhotoBtn.setOnClickListener(v -> {
            if (!checkDvrSdcardExists()) {
                return;
            }
            if (mCameraWorker != null) {
                mCameraWorker.doCapture();
            }
        });
        mRecordVideoBtn.setOnTouchListener(mRecordBtnTouchListener);
        mRecordVideoBtn.setOnCheckedChangeListener(mRecordOnCheckedChangeListener);
        mMuteVideoBtn.setOnClickListener(v -> {
            boolean isChecked = mMuteVideoBtn.isChecked();
            LogUtils.d(TAG, "mMuteVideoBtn click isChecked=" + isChecked);
            boolean result = mCameraWorker != null && mCameraWorker.setCameraAudioMuted(isChecked);
            if (!result) {
                mMuteVideoBtn.setChecked(!isChecked);
            }
        });
    }

    @Override
    public void bindWorker(ICameraWorker cameraWorker) {
        mCameraWorker = cameraWorker;
    }

    @Override
    public void updateViewsWhenConfigureChanged() {
        mVideoRecordingIndicatorLay.setBackgroundColor(ContextCompat.getColor(Utils.getApp(), R.color.camera_video_recording_lay_bg_color));
        for (TextView tv : mDayNightFgColorTvs) {
            tv.setTextColor(ContextCompat.getColorStateList(Utils.getApp(), R.color.camera_btn_txt_color));
        }
    }

    @Override
    public void updateOnPhotoTakingStarted() {
        // Display flash animation to indicate that photo was captured
        mView.postDelayed((Runnable) () -> {
            mView.setForeground(new ColorDrawable(Color.WHITE));
            mView.postDelayed((Runnable) () ->
                    mView.setForeground(null), ANIMATION_FAST_MILLIS);
        }, ANIMATION_SLOW_MILLIS);
    }

    @Override
    public void updateOnPictureTaken(boolean successful) {
        LogUtils.d(TAG, "SoundPlayManger updateOnPictureTaken, successful=" +successful);
        if (successful) {
            SoundPlayManger.get().playShootSound();
            updateLatestThumbnail();
        }
    }

    @Override
    public void updateOnVideoRecordingStarted() {
        showVideoRecordingIndicator(true);
        updateVideoRecordingButton(true);
        setVideoRecordingButtonEnable(true);
    }

    @Override
    public void updateOnVideoTaken(boolean successful) {
        LogUtils.d(TAG, "updateOnVideoTaken " + successful);
        showVideoRecordingIndicator(false);
        updateVideoRecordingButton(false);
        setVideoRecordingButtonEnable(true);
    }

    @Override
    public void updateByZoomSupported(boolean isSupported) {
    }

    @Override
    public void showVideoRecordingIndicator(boolean isVisible) {
        mVideoRecordingIndicatorLay.setVisibility(isVisible ? View.VISIBLE : View.GONE);
    }

    @Override
    public void setVideoRecordingTimeText(String hours, String minutes, String seconds) {
        String videoRecordingTime = Utils.getApp().getString(R.string.camera_tv_video_recording_time_text, hours, minutes, seconds);
        mVideoRecordingTimeTxt.setText(videoRecordingTime);
    }

    @Override
    public void toggleSwitchModeLay() {
        // do nothing
    }

    @Override
    public void showSwitchModeLay(boolean isVisible) {
        // do nothing
    }

    @Override
    public void showZoomButton(boolean isVisible) {
        // do nothing
    }

    @Override
    public void setZoomButtonChecked(boolean isChecked) {
        // do nothing
    }

    @Override
    public void setZoomButtonText(float zoomRatio) {
        // do nothing
    }

    @Override
    public void updateWhenPhotoModeChecked() {
        // do nothing
    }

    @Override
    public void updateWhenVideoModeChecked() {
        // do nothing
    }

    @Override
    public void updateVideoRecordingButton(boolean isTakingVideo) {
        LogUtils.d(TAG, "updateVideoRecordingButton " + isTakingVideo);
        mRecordVideoBtn.setChecked(isTakingVideo);
    }

    @Override
    public boolean updateLatestThumbnail() {
        // do nothing, no need to show dvr thumbnail
        return false;
    }

    @Override
    public void setVideoRecordingButtonEnable(boolean isEnable) {
        LogUtils.d(TAG, "setVideoRecordingButtonEnable " + isEnable);
        mRecordVideoBtn.setEnabled(isEnable);
        mMuteVideoBtn.setEnabled(isEnable);
    }

    @Override
    public void setPhotoTimerChecked(boolean isChecked) {
        // do nothing
    }

    @Override
    public void setVideoTimelapseChecked(boolean isChecked) {
        // do nothing
    }

    @Override
    public void setVideoMutedChecked(boolean isChecked) {
        mMuteVideoBtn.setChecked(isChecked);
    }

    @Override
    public void showCountDownLay(boolean isVisible) {
        // do nothing
    }

    @Override
    public void setCountDownText(String text) {
        // do nothing
    }

    @Override
    public void showErrorLay(String errorText) {
        if (TextUtils.isEmpty(errorText)) {
            mErrorDescTxt.setText(R.string.camera_error_desc);
        } else {
            mErrorDescTxt.setText(errorText);
        }
        if (mErrorView.getVisibility() != View.VISIBLE) {
            mErrorView.setVisibility(View.VISIBLE);
        }
    }

    @Override
    public void hideErrorLay() {
        if (mErrorView.getVisibility() != View.GONE) {
            mErrorView.setVisibility(View.GONE);
        }
    }

    @Override
    public Fragment getFragment() {
        return mFragment;
    }

    @Override
    public void showAll(boolean isVisible) {
        if (mView != null) {
            mView.setVisibility(isVisible ? View.VISIBLE : View.GONE);
        }
    }

    /**
     * 判断当前TfCard是否存在
     * @return
     */
    private boolean checkDvrSdcardExists() {
        if (mCameraWorker instanceof DvrCameraWorker) {
            return ((DvrCameraWorker) mCameraWorker).checkDvrSdcardExists();
        }
        return true;
    }
}
